Módulo Redes Sociales: Sesión 6

Departamento de Estadística

Universidad Nacional de Colombia, Sede Bogotá

Equipo de trabajo

Docente del módulo

Monitor del módulo

Código a ejecutar para empezar (de clic en donde en dice “Code”, para desplegar el código, y luego copie y pegue en una sesión abierta de R):

Code
# cambia idioma de la consola de R a español:
Sys.setenv(LANG="es")
# usar 2 cifras significativas y tiende a evitar 
# notación científica (ver ayuda de función: `options`): 
options(digits = 2, scipen = 999) 
# cargar librerías: 
if(!require(igraph)){
  install.packages("igraph"); library(igraph)}
if(!require(sand)){
  install.packages("sand"); library(sand)}

Introducción

La cohesión se refiere a la medida en que subconjuntos de vértices específicos son cohesivos (adherentes) respecto a la relación que define las aristas.

Cliques

Un enfoque para definir la cohesión de una red es mediante la especificación de subgrafos de interés.

Un clan (clique) C de un grafo G=(V,E) es un subconjunto de vértices tal que cada par de vértices distintos son adyacentes, i.e., el subgrafo de G inducido por C es un grafo completo.

Clanes de tamaños más grandes incluyen clanes de tamaños más pequeños.

Cuántos clanes?

Ejemplo

Creación del grafo

Code
# datos
g <- graph(edges = c(1,2,1,3,1,4,1,5,2,3,2,4,2,5,3,4,3,5,4,5,6,7,6,8,7,8,9,10,1,6,2,9,7,9), directed = F)
Y <- as.matrix(get.adjacency(graph = g, names = F))

Visualización

par(mfrow = c(1,2), mar = c(4, 3, 3, 1))
set.seed(42)
plot(g, vertex.size = 20, vertex.color = 0, vertex.label.color = "black", edge.color = "blue4")
corrplot::corrplot(corr = Y, col.lim = c(0,1), method = "color", tl.col = "black", addgrid.col = "gray", cl.pos = "n")

Orden

vcount(g)
[1] 10

Tamaño

ecount(g)
[1] 17

Es un clan?

c1 <- induced_subgraph(graph = g, vids = c(6,7,8))
ecount(c1) == choose(n = vcount(c1), k = 2)
[1] TRUE

Frecuencias de clanes

table(sapply(X = cliques(graph = g, min = 1, max = 10), FUN = length))

 1  2  3  4  5 
10 17 11  5  1 

Un clan maximal (maximal clique) es un clan que no se puede extender incluyendo algún otro vértice.

# clanes maximales
maximal.cliques(graph = g)
[[1]]
+ 2/10 vertices, from abc0d28:
[1] 10  9

[[2]]
+ 3/10 vertices, from abc0d28:
[1] 6 7 8

[[3]]
+ 2/10 vertices, from abc0d28:
[1] 6 1

[[4]]
+ 2/10 vertices, from abc0d28:
[1] 7 9

[[5]]
+ 2/10 vertices, from abc0d28:
[1] 9 2

[[6]]
+ 5/10 vertices, from abc0d28:
[1] 1 2 5 4 3

Un clan máximo (maximum clique) es el clan maximal más grande.

El número clan (clique number) es el tamaño del clan máximo.

# clanes máximos
largest.cliques(graph = g)
[[1]]
+ 5/10 vertices, from abc0d28:
[1] 1 2 5 4 3
# número clan
clique.number(graph = g)
[1] 5

En la práctica, clanes “grandes” son escasos, ya que requieren que el grafo sea denso, pero las redes reales comúnmente son dispersas (sparse).

Díadas y tríadas

Otras cantidades de interés son las díadas y las tríadas.

¿Cuáles son los estados diádicos no dirigidos y dirigidos?

¿Y los triádicos?

Estados triádicos no dirigidos (undirected triadic motifs):

Estados triádicos dirigidos (directed triadic motifs):

Davis, J.A. and Leinhardt, S. (1972). The Structure of Positive Interpersonal Relations in Small Groups. In J. Berger (Ed.), Sociological Theories in Progress, Volume 2, 218-251. Boston: Houghton Mifflin.

Un censo de los estados diádicos o triádicos proporciona una medida de la conectividad de una red.

Ejemplo: Reforma Tributaria en Colombia.

Red de influencia en Twitter (ahora X) sobre la Reforma Tributaria en Colombia, en el contexto de su aprobación en el Congreso.

Estos datos fueron recolectados para estudiar las dinámicas de interacción entre usuarios de la red social, en relación con las opiniones sobre la Reforma Tributaria.

Los usuarios están conectados mediante aristas ponderadas por el número de interacciones (tuits, retuits, citas y comentarios) relacionadas con el tema.

El artículo asociado a estos datos puede ser encontrado aquí.

Ejemplo

Datos

load('out_refTrib.RData')

Grafo

g
IGRAPH ed81599 DN-- 634 755 -- 
+ attr: name (v/c), Grupo (v/n)
+ edges from ed81599 (vertex names):
 [1] DavidRacero   ->Dikarlosy       laurisarabia  ->torres1951     
 [3] MiguelPoloP   ->andrscast       MiguelPoloP   ->gut_benjamin   
 [5] ELTIEMPO      ->ALH_Siyose      petrogustavo  ->chiscohiguera  
 [7] marcelamvz    ->JALEJO1972      ELTIEMPO      ->russo77lds     
 [9] ArgiroCasta888->Juancas35019169 MiguelUribeT  ->RenaldoRicardo 
[11] ghitis        ->JALEJO1972      MiguelPoloP   ->germanquintero 
[13] alertaLatam   ->Johnecheverri5  susanamuhamad ->JRodrigoBolanos
[15] petrogustavo  ->jorgeccruz1     alertaLatam   ->MariaMa40022334
+ ... omitted several edges

Orden

(n <- vcount(g))
[1] 634

Tamaño

ecount(g)
[1] 755

Es dirigida?

is_directed(g)
[1] TRUE

Es ponderada?

is_weighted(g)
[1] FALSE

Visualización

Code
set.seed(123)
par(mfrow = c(1,1), mar = c(4, 3, 3, 1))
plot(g, layout = layout_with_kk, vertex.label = NA, vertex.size = 3, vertex.frame.color = 1, edge.arrow.size = 0.5, main = "")

Censo de estados triádicos

#   003   A,B,C, el grafo vacío.
#   012   A->B, C, el grafo con un único borde dirigido.
#   102   A<->B, C, el grafo con una conexión mutua entre dos vértices.
#   021D  A<-B->C, la estrella con conexiones salientes (out-star).
#   021U  A->B<-C, la estrella con conexiones entrantes (in-star).
#   021C  A->B->C, línea dirigida.
#   111D  A<->B<-C.
#   111U  A<->B->C.
#   030T  A->B<-C, A->C.
#   030C  A<-B<-C, A->C.
#   201   A<->B<->C.
#   120D  A<-B->C, A<->C.
#   120U  A->B<-C, A<->C.
#   120C  A->B->C, A<->C.
#   210   A->B<->C, A<->C.
#   300   A<->B<->C, A<->C, el grafo completo.
triad_census(g)
 [1] 41813597   441642     5493    11540      307        4        0        0
 [9]        1        0        0        0        0        0        0        0

Censo de estados diádicos

#   mut   El número de pares con conexiones mutuas.
#   asym  El número de pares con conexiones no mutuas.
#   null  El número de pares sin conexión entre ellos.
dyad_census(g)
$mut
[1] 0

$asym
[1] 745

$null
[1] 199916

La mayoría de los estados son nulos, y entre aquellos que no lo son, casi todos presentan asimetría, lo que indica una unilateralidad predominante en la forma en que los participantes de la conversación se mencionan en los tuits.

Densidad

La densidad (density) de un grafo se define como la frecuencia relativa de las aristas observadas respecto al potencial de aristas.

Para un subgrafo H=(V_H,E_H) del grafo G=(V,E), la densidad se calcula como \textsf{den(H)}=\frac{|E_H|}{|V_H|(|V_H|-1)/2}\,. En el caso de un digrafo el denominador debe ser |V_H|(|V_H|-1).

La densidad asume valores entre 0 y 1 y se puede interpretar como una medida de qué tan cerca se encuentra H de ser un clan.

Ejemplo:optencion de la densidad en R

Densidad según la fórmula

ecount(g)/(vcount(g)*(vcount(g)-1))
[1] 0.0019

El comando para calcular la densidad en la librería igraph

edge_density(graph = g)
[1] 0.0019

El promedio de las conexiones

Y <- get.adjacency(g,sparse = F)
mean(Y)
[1] 0.0019

Ego networks de Gustavo Petro, con las cuales observaremos el comportamiento de las relaciones en el subgrafo del vecindario del presidente.

g_1  <- induced_subgraph(graph = g, vids = neighborhood(graph = g, order = 1, nodes = 'petrogustavo') [[1]])

Densidad del subgrafo

edge_density(graph = g_1)
[1] 0.0092

Transitividad global

Una tripla está constituida por tres nodos que están conectados por dos (tripla abierta) o tres (tripla cerrada) aristas.

La transitividad (transitivity) de un grafo se cuantifica por medio del coeficiente de agrupamiento (clustering coeffitient) que se calcula como \textsf{cl} (G) =\frac{\text{no. triplas cerradas}}{\text{no. triplas}} =\frac{3\times \text{no. triángulos}}{\text{no. triplas}} = \frac{3\tau_\triangle(G)}{\tau_3(G)}\,, donde \tau_\triangle(G) es el número de triángulos de G y \tau_3(G) es el número de triplas.

El coeficiente de agrupamiento es una medida de agrupamiento global que caracteriza la propensión con la que las triplas forman triángulos.

Transitividad local

El coeficiente de agrupamiento del vértice v\in V se define teniendo en cuenta la incidencia de v en las aristas que conforman las triplas: \textsf{cl}(v) = \frac{\text{no. triplas cerradas que incluyen a $v$}}{k_v(k_v-1)/2}\,, donde k_v es el grado del nodo v.

El coeficiente de agrupamiento de un vértice es una medida de agrupamiento local que cuantifica qué tan cerca están los vecinos del vértice de ser un clan.

Alternativamente, el coeficiente de agrupamiento global también se puede definir como el promedio de los coeficientes de agrupamiento locales de todos los vértices: \textsf{cl} (G) = \frac{1}{|V|}\sum_{v\in V} \textsf{cl}(v)\,.

Ejemplo

Número de triángulos por vértice

head(count_triangles(graph = g),20)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0

Vértices que son parte de un triángulo

triangles(graph = g)
+ 3/634 vertices, named, from ed81599:
[1] Mamertos0       RoyBarreras     FedericoYBabaji

Conteos de estados triádicos

(mot <- motifs(graph = g, size = 3))
 [1]    NA    NA   307    NA     4     0 11540     1     0     0     0     0
[13]     0     0     0     0

Transitividad global

transitivity(graph = g, type = "global")
[1] 0.00025

Transitividad local

head(sort(transitivity(graph = g, type = "local"),decreasing = T))
FedericoYBabaji     RoyBarreras       Mamertos0     DavidRacero    laurisarabia 
          1.000           0.100           0.067           0.000           0.000 
    MiguelPoloP 
          0.000 

Transitividad global alternativa

mean(transitivity(graph = g, type = "local", vids = V(g)), na.rm = T)
[1] 0.0058

Intransitividad local de Gustavo Petro

transitivity(g, type = "local", vids = c('petrogustavo'))
petrogustavo 
           0 

Reciprocidad

Un concepto exclusivo de los dígrafos es la reciprocidad, i.e., la propensión con la que hay reciprocidad de aristas en la red.

Las frecuencias se pueden calcular respecto al número de díadas o de aristas: \textsf{rec}(G) = \frac{\text{no. aristas reciprocas}}{\text{no. aristas}}\,, o alternativamente, \textsf{rec}(G) = \frac{\text{no. diadas reciprocas}}{\text{no. diadas no reciprocas}}\,.

Ejemplo

Reciprocidad (aristas)

reciprocity(g, mode = "default")
[1] 0

Reciprocidad (díadas)

reciprocity(g, mode = "ratio")
[1] 0

Conectividad

Comúnmente una de las componentes conectadas de un grafo G=(V,E) domina a las demás en magnitud. Tal componente se denomina componente gigante (giant component).

En la práctica, la atención se restringe a la componente gigante para llevar a cabo tanto el análisis como el modelamiento.

Un grafo G=(V,E) se llama k-conectado (k-connected) si |V|>k y la remoción de cualquier subconjunto de vértices X \subset V tal que |X| < k da como resultado un subgrafo que continua estando conectado.

Conectividad nodal

La conectividad nodal de un grafo G=(V,E) corresponde al entero más grande k tal que G es k-conectado.

Alternativamente, también se puede definir como el número mínimo de nodos que deben eliminarse para desconectar el grafo.

Un vértice que la ser removido desconecta el grafo se denomina vértice de corte (cut vertex) o punto de articulación (articulation point).

La identificación de tales vértices proporciona una idea de dónde es vulnerable una red.

Ejemplo

Creación de la red

f <- graph(edges = c(1,2,1,3,2,3,1,4,4,5), directed = F)

Visualización

set.seed(123)
plot(f, vertex.size = 20, vertex.color = 0, vertex.label.color = "black", edge.color = "blue4")

La red esta conectada?

is_connected(f)
[1] TRUE

K-conectividad

vertex_connectivity(f)
[1] 1
edge_connectivity(f)
[1] 1

Puntos de articulación

articulation_points(f)
+ 2/5 vertices, from ad6e772:
[1] 4 1